package uba.ing2.subite.services.authorizationrules;

import uba.ing2.subite.domain.DisposableCard;
import uba.ing2.subite.domain.Invoice;
import uba.ing2.subite.domain.PaymentCard;
import uba.ing2.subite.domain.PaymentCardVisitor;
import uba.ing2.subite.domain.PrepaidCard;
import uba.ing2.subite.services.AccountService;
import uba.ing2.subite.services.PaymentAuthorizationResult;

public class BalanceVerificationRule implements PaymentAuthorizationRule {
	private AccountService accountService;

	public BalanceVerificationRule(AccountService accountService) {
		this.accountService = accountService;
	}

	@Override
	public PaymentAuthorizationResult apply(Invoice invoice, PaymentCard card) {
		CardVisitor cardVisitor = new CardVisitor(invoice.total());
		card.accept(cardVisitor);
		return cardVisitor.result;
	}

	public class CardVisitor implements PaymentCardVisitor {
		public PaymentAuthorizationResult result;
		private Number total;

		public CardVisitor(Number total) {
			this.total = total;
		}

		@Override
		public void visitDisposableCard(DisposableCard disposableCard) {
			result = PaymentAuthorizationResult.createFromCondition(
					disposableCard.moneyAvailable().doubleValue() >= total.doubleValue(), "Tarjeta sin saldo");
			
		}

		@Override
		public void visitPrepaidCard(PrepaidCard prepaidCard) {
			result = PaymentAuthorizationResult.createFromCondition(
					accountService.balanceOnCurrentTimeForAccountIdentifiedBy(prepaidCard.accountIdentifier()).doubleValue() >= total.doubleValue(),
							"Saldo de cuenta insuficiente");
		}
	}
}
